package co.edu.usbcali.unidad.dataaccess.dao;

import co.edu.usbcali.unidad.dataaccess.sessionFactory.HibernateSessionFactory;
import co.edu.usbcali.unidad.modelo.Reserva;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;

import org.hibernate.criterion.Example;

import java.math.BigDecimal;

import java.util.Date;
import java.util.List;
import java.util.Set;

public class ReservaDAO implements IReservaDAO {
	private static final Log log = LogFactory.getLog(ReservaDAO.class);

	// property constants
	// public static final String RESCODIGO = "resCodigo";
	public static final String RESCODIGO = "resCodigo";

	// public static final Date RESFECHA = "resFecha";
	public static final String RESFECHA = "resFecha";

	// public static final Date RESHORAFIN = "resHoraFin";
	public static final String RESHORAFIN = "resHoraFin";

	// public static final Date RESHORAINICIO = "resHoraInicio";
	public static final String RESHORAINICIO = "resHoraInicio";

	private Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	/**
	 * 
	 * @param Instance
	 *            Reserva Instance to persist
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void save(Reserva instance) {
		log.debug("saving Reserva instance");

		try {
			getSession().save(instance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	/**
	 * @param Instance
	 *            Reserva Instance to delete
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void delete(Reserva instance) {
		log.debug("deleting Reserva instance");

		try {
			getSession().delete(instance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	/**
	 * 
	 * @param Instance
	 *            Reserva Instance to update
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void update(Reserva instance) {
		log.debug("updating Reserva instance");

		try {
			getSession().update(instance);
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
			throw re;
		}
	}

	public Reserva findById(String id) {
		log.debug("finding Reserva instance with id: " + id);

		try {
			Reserva instance = (Reserva) getSession().get(Reserva.class, id);

			return instance;
		} catch (RuntimeException re) {
			log.error("finding Reserva failed", re);
			throw re;
		}
	}

	public List<Reserva> findByExample(Reserva instance) {
		log.debug("finding Reserva instance by example");

		try {
			List results = getSession().createCriteria("Reserva").add(
					Example.create(instance)).list();
			log.debug("find by example successful, result size: "
					+ results.size());

			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	/**
	 * Find all Reserva entities with a specific property value.
	 * 
	 * @param value
	 *            the property value to match
	 * @param propertyName
	 *            the property to search in the instance
	 * @return List< Reserva> found by query
	 */
	public List<Reserva> findByProperty(String propertyName, Object value) {
		log.debug("finding Reserva instance with property: " + propertyName
				+ ", value: " + value);

		try {
			String queryString = "from Reserva as model where model."
					+ propertyName + "= ?";
			Query queryObject = getSession().createQuery(queryString);
			queryObject.setParameter(0, value);

			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List<Reserva> findByResCodigo(Object resCodigo) {
		return findByProperty(RESCODIGO, resCodigo);
	}

	public List<Reserva> findByResFecha(Object resFecha) {
		return findByProperty(RESFECHA, resFecha);
	}

	public List<Reserva> findByResHoraFin(Object resHoraFin) {
		return findByProperty(RESHORAFIN, resHoraFin);
	}

	public List<Reserva> findByResHoraInicio(Object resHoraInicio) {
		return findByProperty(RESHORAINICIO, resHoraInicio);
	}

	/**
	 * Find all Reserva entities.
	 * 
	 * @return List<Reserva> all Reserva instances
	 */
	public List<Reserva> findAll() {
		log.debug("finding all Reserva instances");

		try {
			String queryString = "from Reserva";
			Query queryObject = getSession().createQuery(queryString);

			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	public List<Reserva> horaFecha(Date fecha){
		log.debug("finding consult date");
		try{
			String queryString = "select * from reserva where res_hora_inicio = '"+fecha+"'";
			Query queryObject  = getSession().createQuery(queryString);
			
			return queryObject.list();
		}catch (Exception e) {
			// TODO: handle exception
			log.error("find failed", e);
		}
		return null;
		
	}
	public List<Reserva> findByCriteria(String whereCondition) {
		log.debug("finding Reserva " + whereCondition);

		try {
			String where = ((whereCondition == null) || (whereCondition
					.length() == 0)) ? "" : ("where " + whereCondition);
			final String queryString = "select model from Reserva model "
					+ where;
			Query query = getSession().createQuery(queryString);
			List<Reserva> entitiesList = query.list();

			return entitiesList;
		} catch (RuntimeException re) {
			log.error("find By Criteria in Reserva failed", re);
			throw re;
		}
	}

	public List<Reserva> findPageReserva(String sortColumnName,
			boolean sortAscending, int startRow, int maxResults) {
		log.debug("finding Reserva findPageReserva");

		if ((sortColumnName != null) && (sortColumnName.length() > 0)) {
			try {
				String queryString = "select model from Reserva model order by model."
						+ sortColumnName
						+ " "
						+ (sortAscending ? "asc" : "desc");

				return getSession().createQuery(queryString).setFirstResult(
						startRow).setMaxResults(maxResults).list();
			} catch (RuntimeException re) {
				throw re;
			}
		} else {
			try {
				String queryString = "select model from Reserva model";

				return getSession().createQuery(queryString).setFirstResult(
						startRow).setMaxResults(maxResults).list();
			} catch (RuntimeException re) {
				throw re;
			}
		}
	}

	public Long findTotalNumberReserva() {
		log.debug("finding Reserva count");

		try {
			String queryString = "select count(*) from Reserva model";
			Query queryObject = getSession().createQuery(queryString);

			return (Long) queryObject.list().get(0);
		} catch (RuntimeException re) {
			throw re;
		}
	}
	
    public List<Reserva> buscarPorCodigo(String codInmueble, String txtNombCon) {
        log.debug("finding all Reserva instances");


        try {
            String queryString = "from Reserva where propietarioInmueble.priCodigo=:codigo and resCodigo like '%"+txtNombCon+"%'";
            Query queryObject = getSession().createQuery(queryString);
            queryObject.setParameter("codigo", codInmueble);
            return queryObject.list();
        } catch (RuntimeException re) {
            log.error("find all failed", re);
            throw re;
        }
    }
    
    public List<Reserva> buscarFecha(String fecha) {
    	log.debug("finding all Reserva instances");
        try {
            //String queryString = "select a from Autorizacion a, Usuario u where(u.usuContrasena=:usu and a.autCodigo=:codigo)";
        	String queryString = "from Reserva where to_date('"+fecha+"', 'DD/MM/YYYY HH24:MI') between res_hora_inicio and res_hora_fin";
            Query queryObject = getSession().createQuery(queryString);
            //queryObject.setParameter("fecha", fecha);  
            return queryObject.list();
    } catch (RuntimeException re) {
        log.error("find all failed", re);
        throw re;
    }
}
}
